<?php
declare (strict_types=1);

namespace catchAdmin\diseasepath\controller;

use app\common\business\Patient;
use app\common\lib\ZhyxBeanstalkd;
use app\common\lib\ZhyxMongo;
use app\common\model\BaseModel;
use app\common\model\BindDiseasePath;
use app\common\model\DiseasePatientTask;
use app\common\model\DiseasePatientTaskDetail;
use app\common\model\PatientInfo;
use catchAdmin\diseasepath\request\BindDiseasePathRequest;
use catchAdmin\diseasepath\request\DiseasePathRequest;
use catcher\base\CatchRequest;
use catcher\CatchResponse;
use catcher\exceptions\CatchException;
use catcher\exceptions\FailedException;
use catcher\exceptions\ValidateFailedException;
use catcher\library\client\Response;
use catcher\Utils;
use MongoDB\BSON\ObjectId;
use think\exception\ValidateException;
use think\Request;
use voku\helper\AntiXSS;

class DiseasePath
{
    protected $business = null;

    public function __construct()
    {
        $this->business = new \app\common\business\DiseasePath();
    }


    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index()
    {
        return CatchResponse::paginate((new \app\common\model\DiseasePath())->getLists());
    }

    /**
     * 保存新建的资源
     *
     * @param \think\Request $request
     * @return \think\Response
     */
    public function save(DiseasePathRequest $request): \think\Response
    {
        try {
            $postData = $request->post();

            $postData['creator_name'] = ($request->user())->username;
            //根据传递过来的值进行慢病随访路径的创建操作
            $result = $this->business->createData($postData);
            if ($result !== false) {
                return CatchResponse::success(["id" => $result]);
            }
            return CatchResponse::fail("慢病随访路径创建失败");
        } catch (ValidateFailedException $validateFailedException) {
            throw new ValidateFailedException($validateFailedException->getMessage());
        } catch (\Exception $exception) {
            throw new FailedException($exception->getMessage());
        }
    }

    /**
     * 显示指定的资源
     *
     * @param string $id
     * @return \think\Response
     */
    public function read(string $id): \think\Response
    {
        if (empty(trim($id))) {
            throw new ValidateFailedException("随访路径ID不存在");
        }
        $result = $this->business->model->find(new ObjectId($id));
        if (empty($result)) {
            throw new FailedException("随访记录不存在");
        }
        return CatchResponse::success($result->toArray());

    }

    /**
     * 保存更新的资源
     *
     *
     * @param string $id
     * @return \think\Response
     */
    public function update(DiseasePathRequest $request, string $id)
    {
        try {
            $postData = $request->put();

            //根据传递过来的值进行慢病随访路径的创建操作
            $result = $this->business->updateData($postData, $id);
            if ($result !== false) {
                return CatchResponse::success(["result" => $result]);
            }
            return CatchResponse::fail("慢病随访路径创建失败");
        } catch (ValidateFailedException $validateFailedException) {
            throw new ValidateFailedException($validateFailedException->getMessage());
        } catch (\Exception $exception) {
            throw new FailedException($exception->getMessage());
        }
    }

    /**
     * 删除指定资源
     *
     * @param int $id
     * @return \think\Response
     */
    public function delete($id)
    {
        return CatchResponse::success($this->business->model->destroy($id));
    }

    public function bindDiseasePath(BindDiseasePathRequest $request): \think\response\Json
    {
        $postData = $request->param();
        if (isset($postData["is_all"]) && $postData["is_all"] === true) {
            $patientIds = (new PatientInfo())->getAllPatientIds($postData["group_id"] ?? "", $request->user()['id']);
        } else {
            $patientIds = $postData["patients"];
        }

        //执行患者与随访任务的创建投递
        foreach ($patientIds as $k => $v) {
            $errorTimes = 0;
            $taskData = [
                'patientId' => $v,
                'doctors' => $postData["doctors"],
                'disease_path' => $postData["disease_paths"],
                'creator_name' => ($request->user())->username,
                'creator_id' => ($request->user())->id,
                'tubeName' => 'SendDiseasePathPlan',
            ];
            try {
                $deliveryTask = ZhyxBeanstalkd::getInstance()->beansTalk->useTube("sendDiseasePathPlan")->put(json_encode($taskData, JSON_THROW_ON_ERROR), 0, 0);
            } catch (\Exception $exception) {
                $errorTimes++;
                if ($errorTimes > 3) {
                    throw new FailedException("随访路径任务投递失败");
                }
                $deliveryTask = ZhyxBeanstalkd::getInstance()->beansTalk->useTube("sendDiseasePathPlan")->put(json_encode($taskData, JSON_THROW_ON_ERROR), 0, 0);
            }
        }
        return CatchResponse::success("任务投递成功");
    }

    public function unBind(CatchRequest $request)
    {
        $postData = $request->param();
        if (isset($postData["is_all"]) && $postData["is_all"] === true) {
            $patientIds = (new PatientInfo())->getAllPatientIds($postData["group_id"] ?? "", $request->user()['id']);
        } else {
            $patientIds = $request->param("patients", []);
        }

        if (empty($patientIds)) {
            throw new ValidateException("请传入要取消的患者id");
        }

        $diseaseId = $request->param("disease_id", "", "string");
        if (empty($diseaseId)) {
            throw new ValidateException("随访路径ID不能为空");
        }
        $bindIds = $result = (new BindDiseasePath())->where([["disease_path_id", "=", $diseaseId], ["patient_id", "in", $patientIds]])->column("id");

        $result = (new BindDiseasePath())->where([["disease_path_id", "=", $diseaseId], ["patient_id", "in", $patientIds]])->save([
            "deleted_at" => time()
        ]);

        if ($result !== false) {
            foreach ($bindIds as $k => &$v) {
                $v = new ObjectId($v);
            }
            (new DiseasePatientTask())->where([["bind_id", "in", $bindIds], ["patient_id", "in", $patientIds]])->save([
                'deleted_at' => time()
            ]);

            return CatchResponse::success("删除成功");
        }
        return CatchResponse::fail("删除失败");
    }

    public function getTaskDetail(CatchRequest $request): \think\response\Json
    {
        $taskId = $request->param("task_id", "", "string");
        if (empty($taskId)) {
            throw new ValidateException("任务id必须填写");
        }
        /* $result = (new DiseasePatientTaskDetail())->field(["create_by", "creator_id", "attachment_title", "attachment_value", "task_type", "task_name", "task_id", "id"])->where([["task_id", "=", new ObjectId($taskId)]])->order("id", "asc")->select();
         */
        $collection = ZhyxMongo::getInstance()->setCollection('disease_patient_task_detail');
        $cursor = $collection->aggregate([['$match' => ['task_id' => new ObjectId($taskId), 'latest_status' => ['$gte' => 1]]], ['$group' => ['_id' => ['task_date' => '$task_start_date', 'task_type' => '$task_type', 'task_name' => '$task_name'], 'creator_by' => ['$first' => '$creator_by'], 'details' => ['$addToSet' => ['task_date' => '$task_start_date', 'task_name' => '$task_name', 'attachment_title' => '$attachment_title', 'attachment_value' => '$attachment_value', 'latest_status' => '$latest_status', 'creator_id' => '$creator_id', 'creator_by' => '$creator_by', 'task_type' => '$task_type']]]], ['$group' => ['_id' => '$_id.task_date', 'creator_by' => ['$first' => '$creator_by'], 'details' => ['$addToSet' => '$$ROOT']]]]);
        $result = iterator_to_array($cursor);
        foreach ($result as $k => $v) {
            foreach ($v["details"] as $dk => $dv) {
                foreach ($dv["details"] as $kk => &$vv) {
                    $vv["latest_status_text"] = Utils::getLatestStatus($vv["latest_status"]);
                }
            }
        }

        return CatchResponse::success($result);
    }

    public function getPatientDisease(Request $request): \think\response\Json
    {
        $patientId = $request->param("patient_id", "", "string");
        if (empty($patientId)) {
            throw new ValidateException("患者ID不能为空");
        }
        $result = (new BindDiseasePath())->getLists($patientId);
        return CatchResponse::success($result);
    }

    public function calcDiseasePlan(CatchRequest $request): \think\response\Json
    {

        $diseaseId = $request->param("disease_id", "", "string");
        if (empty($diseaseId)) {
            throw new ValidateException("随访路径ID");
        }
        $result = (new DiseasePatientTaskDetail())->getListByDiseaseId($diseaseId);
        return CatchResponse::success($result);

    }

    public function schemeDetails(CatchRequest $request): \think\response\Json
    {
        $taskId = $request->param("task_id", "", "string");
        if (empty($taskId)) {
            throw new ValidateException("任务ID不能为空");
        }
        $result = (new DiseasePatientTaskDetail())->getSchemeDetailsByTaskId($taskId);
        return CatchResponse::success($result);
    }

    public function getDiseasePatient(CatchRequest $request): \think\response\Json
    {
        $userId = $request->user()->id;

        $condition = [["doctors.doctor_id|creator_id", "=", $userId], ["deleted_at", "=", 0]];
        $patientName = $request->param("patient_name", "", "string");
        if (!empty($patientName)) {
            $condition[] = ["patient_name", 'like', $patientName];
        }
        $date = $request->param("date", []);
        if (!empty($date)) {
            $condition[] = ["created_at", ">=", strtotime($date[0])];
            $condition[] = ["created_at", "<=", strtotime($date[1])];
        }
        $result = (new BindDiseasePath())->where($condition)->order('id', "desc")->paginate(10);
        /*if ($result !== null) {
            foreach ($result->items() as $k => &$v) {

                $patientInfo = (new PatientInfo())->getPatientInfo($v["patient_id"], "1");
                $v["patient_name"] = $patientInfo["name"] ?? "";
                $v["sex"] = $patientInfo["sex"] ?? "";
                $v["telephone"] = $patientInfo["presentTelphone"] ?? "";

            }
        }*/
        return CatchResponse::paginate($result);
    }

    public function closeCase(CatchRequest $request): \think\response\Json
    {
        $diseasePathId = $request->param("disease_path_id", "", "string");
        if (empty(trim($diseasePathId))) {
            throw new ValidateFailedException("慢病路径ID不能为空");
        }
        $conclusion = $request->param("conclusion", "", "string");
        $conclusion = htmlspecialchars($conclusion, ENT_NOQUOTES | ENT_SUBSTITUTE | ENT_HTML5, 'UTF-8');
        if (empty($conclusion)) {
            throw new ValidateFailedException("结案说明不能为空");
        }
        $result = $this->business->closeCase($diseasePathId, $conclusion);
        if ($result) {
            return CatchResponse::success("结案成功");
        }
        return CatchResponse::fail("结案失败");

    }

    public function setStartPoint(CatchRequest $request): \think\response\Json
    {
        $diseasePathId = $request->param("disease_path_id", "", "string");
        if (empty(trim($diseasePathId))) {
            throw new ValidateFailedException("慢病路径ID不能为空");
        }
        $point = $request->param("point", 0, "int");
        if ($point <= 0) {
            throw  new ValidateFailedException("起点index不能为空");
        }
        $result = $this->business->setStartPoint($diseasePathId, $point);

        if ($result) {
            return CatchResponse::success("设置成功");
        }
        return CatchResponse::fail("设置失败");
    }

    public function setRemarkByPoint(CatchRequest $request): \think\response\Json
    {
        $taskId = $request->param("task_id", "", "string");
        if (empty(trim($taskId))) {
            throw new ValidateFailedException("慢病路径任务ID不能为空");
        }
        $remark = $request->param("remark", "", "string");
        $remark = htmlspecialchars($remark, ENT_NOQUOTES | ENT_HTML5);
        if (empty($remark)) {
            throw new ValidateFailedException("备注不能为空");
        }
        $result = (new DiseasePatientTask())->where("id", "=", $taskId)->save(["remark" => $remark]);
        return CatchResponse::success($result);

    }

    public function stopPoint(CatchRequest $request): \think\response\Json
    {
        $diseasePathId = $request->param("disease_path_id", "", "string");
        if (empty(trim($diseasePathId))) {
            throw new ValidateFailedException("慢病路径ID不能为空");
        }
        $diseasePatientInfo = (new BindDiseasePath())->where("id", "=", $diseasePathId)->find();
        if (empty($diseasePatientInfo)) {
            throw new FailedException("数据不存在");
        }
        $remark = $request->param("remark", "", "string");
        if (empty(trim($remark))) {
            throw new ValidateFailedException("中止原因不能为空");
        }

        //判断当前患者是否绑定随访孕周任务
        $rst = (new DiseasePatientTaskDetail())->where([["patient_id", "=", $diseasePatientInfo["patient_id"]], ['latest_status', "=", 0]])->update([
            'latest_status' => 4
        ]);
        if ($rst !== false) {
            (new DiseasePatientTask())->where("bind_id", "=", new ObjectId($diseasePathId))->where("planList.plan_task_status", "=", 0)->save([
                'planList.$.plan_task_status' => 4
            ]);

            $diseasePatientInfo->save(["is_stop" => true, 'remark' => $remark]);
        }
        return CatchResponse::success();
    }


}
